﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Nirvana
{
    /// <summary>
    /// 用于对象Disable,Enable时，快速恢复原来的动画状态，避免条件出发的动画错乱
    /// </summary>
    [RequireComponent(typeof(Animator))]
    public class PreserveAnimatorOnDisable : MonoBehaviour
    {
        private struct AnimatorParamsBinds
        {
            public AnimatorControllerParameterType parameterType;
            public int nameHash;
            public object paramsValue;
        }
        private Animator m_animator;
        private List<AnimatorParamsBinds> aniParamsList = new List<AnimatorParamsBinds>();
        private List<int> aniNameHashList = new List<int>();
        
        void Start()
        {
            this.m_animator = GetComponent<Animator>();
        }

        void OnDisable()
        {
            if (this.m_animator == null || this.m_animator.runtimeAnimatorController == null) return;

            foreach(var p in this.m_animator.parameters)
            {
                var binds = default(AnimatorParamsBinds);
                binds.parameterType = p.type;
                binds.nameHash = p.nameHash;
                switch (binds.parameterType)
                {
                    case AnimatorControllerParameterType.Float:
                        binds.paramsValue = this.m_animator.GetFloat(binds.nameHash);
                        break;
                    case AnimatorControllerParameterType.Int:
                        binds.paramsValue = this.m_animator.GetInteger(binds.nameHash);
                        break;
                    case AnimatorControllerParameterType.Bool:
                        binds.paramsValue = this.m_animator.GetBool(binds.nameHash);
                        break;
                }
                this.aniParamsList.Add(binds);
            }
            int count = this.m_animator.layerCount;
            for(int i = 0; i < count; i++)
            {
                var stateinfo = this.m_animator.GetCurrentAnimatorStateInfo(i);
                this.aniNameHashList.Add(stateinfo.shortNameHash);
            }

        }

        void OnEnable()
        {
            foreach(var p in this.aniParamsList)
            {
                switch (p.parameterType)
                {
                    case AnimatorControllerParameterType.Float:
                        this.m_animator.SetFloat(p.nameHash,(float)p.paramsValue);
                        break;
                    case AnimatorControllerParameterType.Int:
                        this.m_animator.SetInteger(p.nameHash, (int)p.paramsValue);
                        break;
                    case AnimatorControllerParameterType.Bool:
                        this.m_animator.SetBool(p.nameHash, (bool)p.paramsValue);
                        break;
                }
            }

            this.aniParamsList.Clear();
            for(int i = 0; i < this.aniNameHashList.Count; i++)
            {
                this.m_animator.Play(this.aniNameHashList[i], i);
            }
            this.aniNameHashList.Clear();
        }
        
    }
}

